//
//  AESCrypt.m
//  Gurpartap Singh
//
//  Created by Gurpartap Singh on 06/05/12.
//  Copyright (c) 2012 Gurpartap Singh
// 
// 	MIT License
// 
// 	Permission is hereby granted, free of charge, to any person obtaining
// 	a copy of this software and associated documentation files (the
// 	"Software"), to deal in the Software without restriction, including
// 	without limitation the rights to use, copy, modify, merge, publish,
// 	distribute, sublicense, and/or sell copies of the Software, and to
// 	permit persons to whom the Software is furnished to do so, subject to
// 	the following conditions:
// 
// 	The above copyright notice and this permission notice shall be
// 	included in all copies or substantial portions of the Software.
// 
// 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// 	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// 	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// 	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// 	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// 	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#import "AESCrypt.h"

#import "NSData+Base64.h"
#import "NSString+Base64.h"
#import "NSData+CommonCrypto.h"

@implementation AESCrypt

+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
  NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
  NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
  return base64EncodedString;
}

+ (NSString *)encrypt:(NSString *)message key:(NSString *)key iv:(NSString *)iv{
//    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];
//    NSData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];
//    //加密向量
//    NSData *encryptedData = [messageData dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:keyData initializationVector:iv options:kCCOptionPKCS7Padding error:0];
    
    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];
    //加密向量
    NSData *encryptedData = [messageData dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:key initializationVector:iv options:kCCOptionPKCS7Padding error:0];
    NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
    return base64EncodedString;
}

+ (NSData *)Encrypt:(NSString *)message key:(NSString *)key iv:(NSString *)iv{
//    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];
//    NSData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];
//    //加密向量
//    NSData *encryptedData = [messageData dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:keyData initializationVector:iv options:kCCOptionPKCS7Padding error:0];
//    NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
    
    NSString *aesStr = [AESCrypt encrypt:message key:key iv:iv];
    NSData *aesData = [aesStr dataUsingEncoding:NSUTF8StringEncoding];
    return aesData;
}


+ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password {
  NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
  NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
  return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}


+ (NSString *)decrypt:(NSString *)base64EncodedString key:(NSString *)key iv:(NSString *)iv{
//
//    NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
//    NSData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];
//
//    NSData *decryptedData = [encryptedData decryptedDataUsingAlgorithm:kCCAlgorithmAES128 key:keyData initializationVector:iv options:kCCOptionPKCS7Padding error:nil];
//
//   // [encryptedData decryptedAES256DataUsingKey:[[key dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
//    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
    
    
    NSData *decryptedData = [AESCrypt Decrypt:base64EncodedString key:key iv:iv];
     return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}

+ (NSData *)Decrypt:(NSString *)base64EncodedString key:(NSString *)key iv:(NSString *)iv{
    
//    NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
//    NSData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];
//    NSData *decryptedData = [encryptedData decryptedDataUsingAlgorithm:kCCAlgorithmAES128 key:keyData initializationVector:iv options:kCCOptionPKCS7Padding error:nil];
    
    NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
    NSData *decryptedData = [encryptedData decryptedDataUsingAlgorithm:kCCAlgorithmAES128 key:key initializationVector:iv options:kCCOptionPKCS7Padding error:nil];
    return decryptedData;
}

 
 /**
 * Converts byte array to hexidecimal useful for logging and fault finding
 * @param bytes
 * @return
 */
//-(NSString *) bytesToHex(byte[]) bytes {
//    const char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
//        '9', 'A', 'B', 'C', 'D', 'E', 'F'};
//    char[] hexChars = new char[bytes.length * 2];
//    int v;
//    for (int j = 0; j < bytes.length; j++) {
//        v = bytes[j] & 0xFF;
//        hexChars[j * 2] = hexArray[v >>> 4];
//        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
//    }
//    return new String(hexChars);
//}

/**
 * converts hexidecimal string without '0x' to byte array for logging and fault findding
 * @param str
 * @return
 */
//private byte[] hexToBytes(String str) {
//    if (str.length() != 32) {
//        return ivBytes;
//    }
//
//    byte[] bytes = new byte[16];
//    for (int i = 0; i < str.length()/2; i++) {
//        String x = str.substring(i*2, i*2 + 2);
//        bytes[i] =  (byte)(0xff & Integer.parseInt(x,16));
//    }
//
//    return bytes;
//}


@end
